#include "StdAfx.h"
#include <JeayeSDK\c_memory.h>
#include <JeayeSDK\CharFun.h>
#include <JeayeSDK\JUrl.h>

inline BYTE* GetEscapeMap()
{
	static BYTE s_byUrlEscapeMap[0x80-0x20] =
	{
		//    ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
		1,0,1,1,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,

		//  @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _
		1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,

		//  ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ DEL
		1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
	};
	return s_byUrlEscapeMap;
}

size_t JUrl_encode(const char *in,char *lpBuffer)
{
	char *op = lpBuffer;
	const char *p = in;

	unsigned char c;
	while (c = *p++)
	{
		if (c>0x20 && c<=0x80 && GetEscapeMap()[c-0x20]==0)
			*op++ = c;
		else
		{
			*op++ = '%';
			*op=0;
			sprintf(op,"%02X",(int)c);
			op+=2;
		}
	}
	*op=0;
	return strlen(lpBuffer);
}

BOOL JUrl_encode(const char * lpszUrl,char *lpBuffer,UINT nBufferSize)
{
	memset(lpBuffer,0,sizeof(char)*nBufferSize);
	if(nBufferSize<strlen(lpszUrl)*3+2) return FALSE;
	JUrl_encode(lpszUrl,lpBuffer);
	return TRUE;
}

void JUrl_encode(const wchar_t * lpszUrl,wchar_t *lpBuffer,UINT nBufferSize)
{
	memset(lpBuffer,0,sizeof(wchar_t)*nBufferSize);
	char *lpResult;
	char *lpBuff;
	int nLen=WideCharToMultiByte(CP_ACP,0,lpszUrl,-1,0,0,0,0);
	lpBuff=C_MALLOCX(char,nLen);
	lpResult=C_MALLOCX(char,nLen*3+2);
	WideCharToMultiByte(CP_ACP,0,lpszUrl,-1,lpBuff,nLen,0,0);
	JUrl_encode(lpBuff,lpResult,nLen*3+1);
	CTW(lpBuffer,nBufferSize,lpBuff);
	C_FREE(lpBuff);
	C_FREE(lpResult);
	return;
}

size_t JUrl_decode( char* pOut ,const char* pIn )
{
	const unsigned char* pSrc;
	UINT nLength = 0;

	for( pSrc = (const unsigned char*)pIn; *pSrc; pSrc++ )
	{
		nLength++;
		if( '%' == *pSrc &&
			isxdigit( *(pSrc+1) ) &&
			isxdigit( *(pSrc+2) ) )
		{
			pSrc += 2;
		}
	}

	PBYTE pDest = (PBYTE)pOut;
	for( pSrc = (const unsigned char*)pIn; *pSrc; pSrc++ )
	{
		if( '%' == *pSrc &&
			isxdigit( *(pSrc+1) ) &&
			isxdigit( *(pSrc+2) ) )
		{
			BYTE byHex1 = toupper( *(pSrc+1) ) - '0';
			if( byHex1 > 9 ) byHex1 -= ( 'A' - ('9'+1) );
			BYTE byHex2 = toupper( *(pSrc+2) ) - '0';
			if( byHex2 > 9 ) byHex2 -= ( 'A' - ('9'+1) );
			*pDest++ = byHex1 * 16 + byHex2;
			pSrc += 2;
		}
		else
		{
			*pDest++ = *pSrc;
		}
	}
	*pDest++=NULL;

	return nLength;
}

void JUrl_decode(const char* lpszEp,char *lpBuffer,UINT nBufferSize)
{
	char *pResult;
	pResult=new char[strlen(lpszEp)+1];
	JUrl_decode(pResult,lpszEp);
	strcpy_s(lpBuffer,nBufferSize,pResult);
	delete[] pResult;
	return ;
}

void JUrl_decode(const wchar_t* lpszEp,wchar_t *lpBuffer,UINT nBufferSize)
{
	char *pResult;
	int nLen	=(int)wcslen(lpszEp)*2;
	char *pBuff	=new char[nLen+2];
	pResult	=new char[nLen+2];
	::WideCharToMultiByte(CP_ACP,0,lpszEp,-1,pBuff,nLen,0,0);
	JUrl_decode(pResult,pBuff);
	delete[] pBuff;
	MultiByteToWideChar(CP_ACP,0,pResult,-1,lpBuffer,nBufferSize);
	delete[] pResult;
	return ;
}

